#!/usr/bin/perl

#====  PROJECT =================================================================
#         NAME:  Clustered Network
#      PURPOSE:  Test Case for a 3 Clustered infection network
#      RETURNS:  True
#===============================================================================


# Initialisation: Basic Infection Network.

use warnings;
use insj_m_network;
#use Math::Random::MT::Perl qw(rand);

#Create the network.
	$network = insj_m_network->new(name => "Clustered Network");
	my $dim=1024;
	my $ran=0;
	my $group1=int($dim*1/3);
	my $group2=int($group1+($dim*1/3));
	for($counter = 1; $counter <= $dim; $counter++){
		$node = $network->create_node( name=> $counter);
		if ($counter <= $group1) {$node->set_state("group",1,0)}
		elsif ($counter > $group1 && $counter <= $group2)  {$node->set_state("group",2,0)}
		else {$node->set_state("group",3,0)}
		}

#Connect the network and set nodes to uninfected.

	@nodes = $network -> get_node_keys();
	$network -> rewind;
	#my $i=1;
	while ($node = $network -> get_next() ){
		#print "\tNode (".$node->get_name.")\n";
		$node -> set_state("VirusA", 0,0);$node -> set_state("VirusA_t", 0,0);
		$node -> set_state("VirusB", 0,0);$node -> set_state("VirusB_t", 0,0);
		
		#Picking a random node key and connecting it.
		for($counter = 1; $counter <= 3; $counter++){	
			@nodes = sort {$a <=> $b} @nodes; 
			
			if($node->get_name <= $group1){
				if(rand() <= 0.8){							
				  	$rnode = $nodes[rand $group1];   
                      	 $node -> add_node( $network -> get_node( $rnode ));
				}
				else{
					$rnode = $nodes[rand ($group2 - $group1) + $group1];   
                     	$node -> add_node( $network -> get_node( $rnode ) );
				}
			}
			elsif($node->get_name > $group1 && $node->get_name <= $group2){
				if(rand() <= 0.8){
					$rnode = $nodes[rand ($group2 - $group1) + $group1];   
                     	$node -> add_node( $network -> get_node( $rnode ) );
				}
				else{
					$rnode = $nodes[rand ($dim - $group2) + $group2];   
                    		 $node -> add_node( $network -> get_node( $rnode ) );
				}

			}
			else{
				if(rand() <= 0.8){
					$rnode = $nodes[rand ($dim - $group2) + $group2];   
                 	    $node -> add_node( $network -> get_node( $rnode ) );
				}
				else{
					$rnode = $nodes[rand $group1];   
                      	 $node -> add_node( $network -> get_node( $rnode ));
				}
		

			}
           }
		
	}			
#Infect a single node.

	$node  = $network -> get_random_node;
	$node -> set_state("VirusA", 1,1); $node -> set_state("VirusA_t", 1,1);

#Print network.
	$network->print;

#Evolve network, transmission probability 10%.
	for($generation = 2; $generation <= 10; $generation++){
		print "-------------Generation $generation-----------\n";
		$network->rewind;
		
		while ( $node = $network -> get_next ){
			
			$node->rewind;

			while ( $edge = $node -> get_next ){
				#The Ruleset.
				if ( $edge -> get_state("VirusA") == 1 ) {
					if ( rand(100) <= 10 and $node->get_state("VirusA") == 0) { $node->set_state("VirusA_t", 1, $generation); 						
						}
					}
				}
			}
		#Temporay states to actual states!
		$network->rewind;
		
		while ( $node = $network -> get_next ){
			if ( $node->get_state("VirusA") != $node->get_state("VirusA_t") ) { 
				$node->set_state("VirusA", $node->get_state("VirusA_t"),$generation);  
				print $node->get_name." got infected.\n";}			
			}

		$network->print;
	}

	
$network->export("test_clustered.gexf", "gephi");
1;


